package lemna.top.chunyu.batch.step4;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.sql.DataSource;

import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepScope;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.database.JdbcPagingItemReader;
import org.springframework.batch.item.database.Order;
import org.springframework.batch.item.database.support.MySqlPagingQueryProvider;
import org.springframework.batch.item.file.FlatFileItemWriter;
import org.springframework.batch.item.file.transform.BeanWrapperFieldExtractor;
import org.springframework.batch.item.file.transform.FormatterLineAggregator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;

import lemna.top.chunyu.batch.config.ChunYunConfig;
import lemna.top.chunyu.batch.config.Constants;
import lemna.top.chunyu.batch.step4.domain.CommPaymentStatement;
import lemna.top.chunyu.utils.DateUtil;
 


@Configuration
public class Step4Config {


	@Autowired
	ChunYunConfig config;

	@Autowired
	Resource step4File;

	@Autowired
	ItemReader<CommPaymentStatement> step4Reader;
	
	@Autowired
	private DataSource dataSource;
	
	@Autowired
	private Step4Callback step4Callback;

	@Autowired
	Step4ItemProcessor step4ItemProcessor;
	
	@Autowired
	public StepBuilderFactory stepBuilderFactory;
	 
	
	
    @Bean 
    @StepScope
    public Resource step2File(@Value("#{jobParameters[date]}") Date date) {

		String dateParam = Constants.sdf1.format(date);
    	String filePath = config.getInputFilePath()+"alipay-"+dateParam+".csv";
        return new FileSystemResource(filePath);
    }

	@StepScope
	@Bean(name="step4Reader")
	protected ItemReader<CommPaymentStatement> reader(@Value("#{jobParameters[date]}") Date date) throws Exception {

		JdbcPagingItemReader<CommPaymentStatement> reader = new JdbcPagingItemReader<CommPaymentStatement>();
		reader.setDataSource(dataSource);
		MySqlPagingQueryProvider  queryProvider =  queryProvider(date);
		reader.setQueryProvider(queryProvider);
		reader.setRowMapper(
				
				(rs, rowNum) ->
				CommPaymentStatement.builder()
                        .serialNumber(rowNum+1)
                        .merchantNo(rs.getString("merchant_no"))
                        .inAccountType(rs.getInt("in_account_type"))
                        .inAccountNo(rs.getString("in_account_no"))
                        .inAccountName(rs.getString("in_account_name"))
                        .liquidationAmount(rs.getDouble("amount"))
                        .currency(rs.getString("currency"))
                        .liquidationBankNo(rs.getString("liquidation_bank_no"))
                        .liquidationMerchantNo(rs.getString("liquidation_merchant_no"))
                        .build()
				
				
		);
		reader.setPageSize(10);
		reader.afterPropertiesSet();
		reader.setSaveState(true);

		return reader;
	}
	
	private MySqlPagingQueryProvider queryProvider(Date date) {
		String startTime = Constants.sdf1.format(date);
		String endTime = Constants.sdf1.format(DateUtil.getNextDayZeroTime(date));
		MySqlPagingQueryProvider queryProvider = new MySqlPagingQueryProvider();
		queryProvider.setSelectClause("SELECT 	merchant_no  ,in_account_no ,in_account_name, in_account_type ,SUM(order_amount)-SUM(refund_amount) amount,SUM(service_charge_rate) fee,currency ,liquidation_bank_no ,liquidation_merchant_no");
		queryProvider.setFromClause("FROM chun_yu_payment_statement  ");
		queryProvider.setWhereClause("WHERE (in_account_type=1 or in_account_type=2) and create_time > str_to_date('"+startTime+" 00:00:00', '%Y-%m-%d %H:%i:%s') and create_time < str_to_date('"+endTime+" 00:00:00', '%Y-%m-%d %H:%i:%s')");
		queryProvider.setGroupClause("GROUP BY merchant_no  ,in_account_no ,in_account_name, in_account_type ,currency ,liquidation_bank_no ,liquidation_merchant_no ");
		Map<String, Order> sortKeys = new HashMap<String, Order>();
		sortKeys.put("in_account_type", Order.ASCENDING);
		sortKeys.put("liquidation_merchant_no", Order.ASCENDING);
		queryProvider.setSortKeys(sortKeys);
		return queryProvider;
	}
	
	@Bean(name="step4Writer")
    public ItemWriter<CommPaymentStatement> writer() {
		FlatFileItemWriter<CommPaymentStatement> writer = new FlatFileItemWriter<CommPaymentStatement>();
		writer.setResource(step4File);
		BeanWrapperFieldExtractor<CommPaymentStatement> fieldExtractor = new BeanWrapperFieldExtractor<CommPaymentStatement>();
		fieldExtractor.setNames(new String[] { "serialNumber", "merchantNo", "outAccountType", "outAccountNo",
				"outAccountName", "inAccountType", "inAccountNo", "inAccountName", "liquidationAmount", "currency",
				"inAccountChannel", "unitNo", "transactionType", "liquidationBankNo", "transactionSummary",
				"additionalInformation", "extendedInformation" });

		FormatterLineAggregator<CommPaymentStatement> lineAggregator = new FormatterLineAggregator<CommPaymentStatement>();
		lineAggregator.setFieldExtractor(fieldExtractor);
		lineAggregator.setFormat("%1s|%1s|%1s|%1s|%1s|%02d|%1s|%1s|%1s|%1s|%1s|%1s|%1s|%1s|%1s|%1s|%1s|");
		writer.setLineAggregator(lineAggregator);

		writer.setEncoding("GBK");
    	writer.setHeaderCallback(step4Callback);
        return writer;
    }
    

    @Bean 
    @StepScope
    protected Resource step4File(@Value("#{jobParameters[date]}")  Date date) {

		String dateParam = Constants.sdf2.format(date);
    	String filePath = config.getOutputFilePath()+"smzf.plrz_"+dateParam+".txt";//smzf.plrz_YYYYMMDD.txt
        return new FileSystemResource(filePath);
    }
    

	@Bean(name="step4")
	public Step step4() throws Exception {
		return stepBuilderFactory.get("step4").<CommPaymentStatement, CommPaymentStatement>chunk(1).reader(step4Reader).processor(step4ItemProcessor)
				.writer(writer()).build();
	}
}
